package com.ruoyi.datastatistics.service.impl;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.util.*;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.ruoyi.datastatistics.mapper.HourUsageDbMapper;
import com.ruoyi.datastatistics.domain.HourUsageDb;
import com.ruoyi.datastatistics.service.IHourUsageDbService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 大表时用量Service业务层处理
 *
 * @author TsingYu
 * @date 2024-08-05
 */
@Slf4j
@Service
public class HourUsageDbServiceImpl extends ServiceImpl<HourUsageDbMapper, HourUsageDb> implements IHourUsageDbService {
    private final HourUsageDbMapper hourUsageDbMapper;

    public HourUsageDbServiceImpl(HourUsageDbMapper hourUsageDbMapper) {
        this.hourUsageDbMapper = hourUsageDbMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addHourUsage(String beginDate, String endDate) {
        Date begin = DateUtils.parseDate(beginDate);
        Date end = DateUtils.parseDate(endDate);
        if (begin == null || end == null) {
            log.error("未指定日期");
            return;
        } else if (DateUtils.differentDaysByMillisecond(end, begin) > Month.JANUARY.maxLength()) {
            log.error("最多计算31天");
            return;
        }
        Calendar bc = Calendar.getInstance();
        bc.setTime(begin);
        bc.set(Calendar.HOUR_OF_DAY, 0);
        bc.set(Calendar.MINUTE, 0);
        bc.set(Calendar.SECOND, 0);
        Calendar ec = Calendar.getInstance();
        ec.setTime(end);
        ec.set(Calendar.HOUR_OF_DAY, 23);
        ec.set(Calendar.MINUTE, 59);
        ec.set(Calendar.SECOND, 59);
        ec.add(Calendar.HOUR_OF_DAY, 1);
        List<HourUsageDb> list = hourUsageDbMapper.selectHourUsageList(bc.getTime(), ec.getTime());
        // 补全所有日期和小时的用量，没有的小时usage用null
        Set<HourUsageDb> allTerminal = new HashSet<>(list);
        List<LocalDate> allDates = DateUtils.generateLocalDateListBetweenTwoDate(beginDate, endDate);

        List<HourUsageDb> hourUsageDbList = new ArrayList<>(allTerminal.size() * allDates.size() * 24);
        for (LocalDate date : allDates) {
            for (int i = 0; i <= LocalTime.MAX.getHour(); i++) {
                for (HourUsageDb usageDb : allTerminal) {
                    HourUsageDb usage = HourUsageDb.builder()
                            .locationNb(usageDb.getLocationNb())
                            .factoryNumber(usageDb.getFactoryNumber())
                            .terminalName(usageDb.getTerminalName())
                            .sheetsId(usageDb.getSheetsId())
                            .sheetsCode(usageDb.getSheetsCode())
                            .sheetsName(usageDb.getSheetsName())
                            .usageDate(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()))
                            .usageHour(i + 1).build();
                    hourUsageDbList.add(usage);
                }
            }
        }
        for (HourUsageDb allDateHours : hourUsageDbList) {
            for (HourUsageDb usage : list) {
                if (allDateHours.equals(usage)
                        && Objects.equals(allDateHours.getUsageDate(), usage.getUsageDate())
                        && Objects.equals(allDateHours.getUsageHour(), usage.getUsageHour())) {
                    allDateHours.setUsage(usage.getUsage());
                }
            }
        }
        if (hourUsageDbList.isEmpty()) {
            return;
        }
        int batchSize = 500;
        List<List<HourUsageDb>> lists = CollectionUtil.split(hourUsageDbList, batchSize);
        for (List<HourUsageDb> split : lists) {
            hourUsageDbMapper.insertOrUpdateHourUsage(split);
        }
    }
}
